package dmxGroupControl.transmitters;

import dmxGroupControl.StatusCode;
import dmxGroupControl.StatusReporting;
import javafx.application.Platform;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import org.jdom2.Element;

import java.util.UUID;

public abstract class Transmitter implements StatusReporting
{
	boolean enabled = true;

    private Color statusColor = Color.BLACK;
    private String statusText = "Not started";
    private Rectangle statusRect = null;
    private Label statusLabel = null;
    public abstract void close();
    public abstract String GetAddress();
    public abstract String GetType();
    protected abstract void SendInternal(byte[] data);
    
    public void Send(byte[] data)
    {
    	if(enabled)
    	{
    		SendInternal(data);
    	}
    }
    
    public boolean GetEnabled()
    {
    	return enabled;
    }
    
    public void SetEnabled(boolean value)
    {
    	this.enabled = value;
    }
    
    public static String[] GetSupportedTypes()
    {
        return new String[] {"serial", "artnet", "sacn" } ;
    }

    @Override
    public Color GetStatusColor()
    {
        return statusColor;
    }

    @Override
    public String GetStatusText()
    {
        return statusText;
    }

    @Override
    public void SetStatusRect(Rectangle rectangle)
    {
        statusRect = rectangle;
        statusRect.setFill(statusColor);
    }

    @Override
    public void SetStatusLabel(Label label)
    {
        statusLabel = label;
        statusLabel.setText(statusText);
    }

    private void UpdateStatus(Color statusColor, String statusText)
    {
        this.statusColor = statusColor;
        this.statusText = statusText;
        if(statusRect != null)
        {
            Platform.runLater(
                () ->
                {
                    statusRect.setFill(statusColor);
                    statusLabel.setText(statusText);
                }
            );
        }
    }

    protected void UpdateStatus(StatusCode code)
    {
        UpdateStatus(code.getColor(), code.getCodeText());
    }

    protected void UpdateStatus(String error)
    {
        UpdateStatus(Color.RED, error);
    }

    protected void UpdateStatus(Exception e)
    {
        UpdateStatus(e.getMessage());
    }

    protected boolean AlreadyGreen()
    {
        return statusColor == Color.GREEN;
    }

    protected boolean AlreadyYellow()
    {
        return statusColor == Color.YELLOW;
    }

    public static Transmitter CreateTransmitter(Element transmitterElement)
    {
        String address = transmitterElement.getAttributeValue("address");
        String type = transmitterElement.getName();
        boolean enabled = Boolean.parseBoolean(transmitterElement.getAttributeValue("enabled"));

        Transmitter transmitter = null;

        switch (type)
        {
            case "enttecTransmitter":
                transmitter = new EnttecProTransmitter(address);
                break;
            case "artnetTransmitter":
                transmitter = new ArtNetTransmitter(
                    address, Integer.parseInt(
                    transmitterElement.getAttributeValue("universeID")
                )
                );
                break;
            case "sacnTransmitter":
                transmitter = new SACNTransmitter(
                    address,
                    Short.parseShort(
                        transmitterElement.getAttributeValue("universeID")
                    ),
                    transmitterElement.getAttributeValue("name"),
                    UUID.fromString(
                        transmitterElement.getAttributeValue("uuid")
                    )
                );
                break;
            case "opcTransmitter":
                transmitter = new OPCTransmitter(
                    address,
                    Integer.parseInt(
                        transmitterElement.getAttributeValue("channel")
                    )
                );
                break;
            default:
                return null;
        }
        transmitter.SetEnabled(enabled);
        return transmitter;
    }
}
